package random

import (
	"fmt"
	"google.golang.org/grpc/balancer"
	"google.golang.org/grpc/balancer/base"
	"google.golang.org/grpc/grpclog"
	"math/rand"
)

// 算法名称
const Name = "random"

var logger = grpclog.Component("random")

// 创建随机算法 builder
func newBuilder() balancer.Builder {
	return base.NewBalancerBuilder(Name, &rrPickerBuilder{}, base.Config{HealthCheck: true})
}

// 注册算法
func init() {
	balancer.Register(newBuilder())
}

type rrPickerBuilder struct{}

func (*rrPickerBuilder) Build(info base.PickerBuildInfo) balancer.Picker {
	logger.Infof("random Picker: Build called with info: %v", info)
	if len(info.ReadySCs) == 0 { // 没有可用子连接的情况。当选择器被调用时，它将始终返回一个 balancer.ErrNoSubConnAvailable 错误
		// 通过UpdateState()阻塞RPC直到有新的选择器可用
		return base.NewErrPicker(balancer.ErrNoSubConnAvailable)
	}
	// 获取连接
	scs := make([]balancer.SubConn, 0, len(info.ReadySCs))

	for sc := range info.ReadySCs {
		scs = append(scs, sc)
	}
	return &rrPicker{
		subConns: scs,
	}
}

type rrPicker struct {
	//connection 连接数组
	subConns []balancer.SubConn
}

func (p *rrPicker) Pick(balancer.PickInfo) (balancer.PickResult, error) {
	subConnsLen := len(p.subConns)
	fmt.Println(" subConnsLen : ", subConnsLen)
	nextIndex := rand.Intn(subConnsLen)

	sc := p.subConns[nextIndex]
	return balancer.PickResult{SubConn: sc}, nil
}
